package com.sne.airways.system.service.impl;

import com.sne.airways.basecore.exceptions.AppException;
import com.sne.airways.basecore.service.impl.BaseServiceImpl;
import com.sne.airways.system.annotation.MethodLog;
import com.sne.airways.system.dao.RoleDAO;
import com.sne.airways.system.dto.TdRoleCheckDTO;
import com.sne.airways.system.dto.TdRoleDTO;
import com.sne.airways.system.enums.ModuleEnum;
import com.sne.airways.system.enums.OpTypeEnum;
import com.sne.airways.system.pojo.*;
import com.sne.airways.system.service.RoleService;
import com.sne.airways.system.utils.AppUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: skyline{http://my.oschina.net/skyline520}
 * Date: 12-11-23
 * Time: 下午5:49
 * To change this template use File | Settings | File Templates.
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl extends BaseServiceImpl implements RoleService {
    @Autowired
    private RoleDAO roleDAO;
    /**
     * 查询角色列表
     *
     * @param roleNo
     * @param roleName
     * @param status
     * @param start
     * @param limit
     * @return
     */
    public List<TdRoleDTO> queryRoleList(String roleNo, String roleName, String status, int start, int limit) throws AppException {
        List<TdRole> roleList = roleDAO.queryRoleList(roleNo, roleName, status, start, limit);
        List<TdRoleDTO> finalList = new ArrayList<TdRoleDTO> ();
        for(TdRole role:roleList){
            TdRoleDTO   dto   = new TdRoleDTO();
            String[] ignoreProperties = {"createUser","modifyUser","users","operations"};
            BeanUtils.copyProperties(role, dto, ignoreProperties);
            //设置创建人
            dto.setCreateUser(role.getCreateUser() ==null?null:role.getCreateUser().getUserName());
            //设置修改人
            dto.setModifyUser(role.getModifyUser() == null ? null : role.getModifyUser().getUserName());
            finalList.add(dto);
        }
        return finalList;
    }

    /**
     * 查询角色记录总数
     * @param roleNo
     * @param roleName
     * @param status
     * @return
     */
    public Integer queryRoleCount(String roleNo, String roleName, String status) throws AppException {
        Integer count = roleDAO.queryRoleCount(roleNo, roleName, status);
        return count;
    }

    /**
     * 保存角色
     * @param roleNo
     * @param roleName
     * @param status
     * @param version
     * @return
     * @throws AppException
     *
     */
    @MethodLog(opType = OpTypeEnum.添加角色,module = ModuleEnum.角色管理)
    public void saveRole(String roleNo, String roleName, String roleDesc, String status, int version) throws AppException {
        int count = roleDAO.queryRoleIsRepeat(null,roleNo,null,null);
        if(count > 0) throw new AppException("角色编码["+roleNo+"]已经存在");
        count = roleDAO.queryRoleIsRepeat(null,null,roleName,null);
        if(count > 0) throw new AppException("角色名称["+roleName+"]已经存在");
        if(count > 0) throw new AppException("角色名称["+roleName+"]已经存在");
        TdRole role = new TdRole();
        role.setRoleNo(roleNo);
        role.setRoleName(roleName);
        role.setRoleDesc(roleDesc);
        role.setVersion(version);
        role.setStatus(status);
        role.setCreateDate(new Date());
        role.setCreateUser(AppUtils.getCurrentUser());
        saveObject(role);
    }

    /**
     * 编辑角色
     * @param roleId
     * @param roleNo
     * @param roleName
     * @param status
     * @param version
     * @return
     * @throws AppException
     *
     */
    @MethodLog(opType = OpTypeEnum.编辑角色,module = ModuleEnum.角色管理)
    public void updateRole(String roleId, String roleNo, String roleName, String roleDesc, String status, int version) throws AppException {
        int count = roleDAO.queryRoleIsRepeat(roleId,roleNo,null,null);
        if(count > 0) throw new AppException("角色编码["+roleNo+"]已经存在");
        count = roleDAO.queryRoleIsRepeat(roleId,null,roleName,null);
        if(count > 0) throw new AppException("角色名称["+roleName+"]已经存在");
        TdRole role = loadObject(TdRole.class,roleId);
        //编辑的时候调用一下这个方法 判断是否是当前的版本数据
        isCurrentVersion(role,version);
        role.setRoleNo(roleNo);
        role.setRoleName(roleName);
        role.setRoleDesc(roleDesc);
        role.setVersion(version);
        role.setStatus(status);
        role.setModifyDate(new Date());
        role.setModifyUser(AppUtils.getCurrentUser());
        updateObject(role);
    }

    /**
     * 根据roleId和version 删除角色对象
     *
     * @param roleId
     * @param version
     * @throws AppException
     *
     */
    @MethodLog(opType = OpTypeEnum.删除角色,module = ModuleEnum.角色管理)
    public void deleteRole(String roleId, int version) throws AppException {
        TdRole role = loadObject(TdRole.class,roleId);
        isCurrentVersion(role,version);
        role.setVersion(version);
        deleteObject(role);
    }

    /**
     * 保存用户角色关联关系
     *
     * @param roleId
     * @param idArray
     * @param version
     * @throws com.sne.airways.basecore.exceptions.AppException
     *
     */
    @Override
    public void saveRoleUser(String roleId, String[] idArray, int version) throws AppException {
        TdRole role = loadObject(TdRole.class,roleId);
        //要删除的用户角色对应列表
        Set<TdUserRole> all_deleted_userRoles = new HashSet<TdUserRole>();
        //要保存的用户角色对应列表
        Set<TdUserRole> all_saved_users = new HashSet<TdUserRole>();
        //得到旧的用户角色列表
        Set<TdUserRole> oldUserRoleSet = role.getUsers();
        //构造要删除的用户角色对应关系对象列表
        for(Iterator<TdUserRole> it = oldUserRoleSet.iterator();it.hasNext();){
            TdUserRole userRole = it.next();
            boolean flag = true;
            for(String id:idArray){
                if((userRole.getUser().getUserId()).equals(id)){
                    flag = false;
                    break;
                }
            }
            if(flag)
                all_deleted_userRoles.add(userRole);
        }
        //构造要保存的用户角色对应关系对象列表
        for(String id:idArray){
            boolean flag = true;
            for(Iterator<TdUserRole> it = oldUserRoleSet.iterator();it.hasNext();){
                TdUserRole userRole = it.next();
                if((userRole.getUser().getUserId()).equals(id)){
                    flag = false;
                    break;
                }
            }
            if(flag){
                TdUser user = loadObject(TdUser.class,id);
                TdUserRole userRole = new TdUserRole();
                userRole.setUser(user);
                userRole.setRole(role);
                all_saved_users.add(userRole);
            }
        }
        //在数据库中删除原先该用户的用户角色对应记录
        deleteCollection(all_deleted_userRoles);
        saveCollection(all_saved_users);
    }

    /**
     * 保存角色资源关联关系
     *
     * @param roleId
     * @param idArray
     * @param version
     * @throws com.sne.airways.basecore.exceptions.AppException
     *
     */
    @Override
    public void saveRoleOperation(String roleId, String[] idArray, int version) throws AppException {
        TdRole role = loadObject(TdRole.class,roleId);
        //要删除的角色资源对应列表
        Set<TdRoleOperation> all_deleted_roleOperations = new HashSet<TdRoleOperation>();
        //要保存的角色资源对应列表
        Set<TdRoleOperation> all_saved_operations = new HashSet<TdRoleOperation>();
        //得到旧的角色资源列表
        Set<TdRoleOperation> oldRoleOperations = role.getOperations();
        //构造要删除的角色资源对应关系对象列表
        for(Iterator<TdRoleOperation> it = oldRoleOperations.iterator();it.hasNext();){
            TdRoleOperation tdRoleOperation = it.next();
            boolean flag = true;
            for(String id:idArray){
                if((tdRoleOperation.getOperation().getOperationId()).equals(id)){
                    flag = false;
                    break;
                }
            }
            if(flag)
                all_deleted_roleOperations.add(tdRoleOperation);
        }
        //构造要保存的用户角色对应关系对象列表
        for(String id:idArray){
            boolean flag = true;
            for(Iterator<TdRoleOperation> it = oldRoleOperations.iterator();it.hasNext();){
                TdRoleOperation tdRoleOperation = it.next();
                if((tdRoleOperation.getOperation().getOperationId()).equals(id)){
                    flag = false;
                    break;
                }
            }
            if(flag&&!"".equals(id)&&id !=null&&!"-1".equals(id)){
                TdOperation operation = loadObject(TdOperation.class,id);
                TdRoleOperation tdRoleOperation = new TdRoleOperation();
                tdRoleOperation.setOperation(operation);
                tdRoleOperation.setRole(role);
                all_saved_operations.add(tdRoleOperation);
            }
        }
        //在数据库中删除原先该用户的用户角色对应记录
        deleteCollection(all_deleted_roleOperations);
        saveCollection(all_saved_operations);
    }

    @Override
    public List<String> queryRoleCheckedList(String userId) throws AppException {
        TdUser user = getObject(TdUser.class,userId);
        Set<TdUserRole> userRoles = user.getRoles();
        List<String> list = new ArrayList<String>(userRoles.size());
        for(TdUserRole userRole : userRoles){
            list.add(userRole.getRole().getRoleId());
        }
        return list;
    }

    @Override
    public void saveUserRole(String userId, String[] ids) throws AppException {
        TdUser user = getObject(TdUser.class,userId);
        Set<TdUserRole> userRoles = user.getRoles();
        deleteCollection(userRoles);
        if(ids!=null){
            for(String id:ids){
                TdRole role = getObject(TdRole.class,id);
                TdUserRole userRole = new TdUserRole();
                userRole.setRole(role);
                userRole.setUser(user);
                saveObject(userRole);
            }
        }

    }
}
